/**
 * Copyright (C) 2008+ Spark Zheng
 *
 * @file	include/confloose.h
 * @brief
 *      loose config module, config file must like:
 *		#this is an annotation
 *		[module1]
 *		key1 = value1
 *		key2 = value2 \
 *		       value2-continued (need notice the space)
 *		[module2]
 *		key3 = value3-1, value3-2
 *
 * @see		dlib
 * @module      dlib
 * @history
 *      version 0.0.1   Spark Zheng init confloose module
 */

#ifndef _DLIB_CONFLOOSE_H
#define _DLIB_CONFLOOSE_H

#ifdef __cplusplus
extern "C" {
#endif

#include "global.h"
#include "list.h"
	
#define DEF_FIELD_NAME		"__dlib_def_field"
	
#define CONFL_STR_MOVE	0		/** get string method, just move */
#define CONFL_STR_COPY	1		/** get string method, need alloc&copy */

#define E_CONFL_ITEM_NOTEXIST	10
#define E_CONFL_ITEM_EXIST	11
#define E_CONFL_FIELD_NOTEXIST	20
#define E_CONFL_FIELD_EXIST	21
	
typedef struct conf_loose {
	hlist_head_t	field_head;	/** confloose field list */
	uint32_t	field_num;	/** count of fields */
	uint32_t	item_num;	/** count of items in all fields */
} dlib_confl_t;

typedef struct confl_field {
	hlist_node_t	field_node;	/** confloose field node */
	hlist_head_t	item_head;	/** confloose item head */
	uint32_t	item_num;	/** count of items in the field */
	char		*field_name;	/** field name */
} dlib_confl_field_t;

typedef struct confl_item {
	hlist_node_t	item_node;	/** confloose item node */
	char		*key;		/** key string */
	char		*value;		/** value string */
} dlib_confl_item_t;

/**
 * dlib_confl_init
 * @brief read the conf file and fill into dlib_confl_t, return confl or NULL.
 * @param file: the config file path.
 */
extern dlib_confl_t *dlib_confl_init(const char *file);

/**
 * dlib_confl_get_integer
 * @brief get an integer from htable, return 0 or < 0(err).
 * @param confl: confloose structure.
 * @param field: the string field.
 * @param key: key to access value.
 * @param integer[OUT]: out container
 */
extern int dlib_confl_get_integer(dlib_confl_t *confl, const char *field,
				  const char *key, long *integer);

/**
 * dlib_confl_get_string
 * @brief get a string from confl, return the string or NULL.
 * @warning WARNING: the return string need to be freed by hand.
 * @param confl: confloose structure
 * @param field: the string field.
 * @param key: the string key.
 * @param type: get string method, MOVE(0) or COPY(1).
 *	MOVE means mv string from item_node, COPY means alloc a buffer, and
 *	copy string from item_node to buffer.
 *	BOTH method need to free return pointer by hand.
 */
extern char *dlib_confl_get_string(dlib_confl_t *confl, const char *field,
				   const char *key, int type);

/**
 * dlib_confl_exit
 * @brief release the memory in confl.
 * @param confl: confloose structure
 */
extern void dlib_confl_exit(dlib_confl_t *confl);

/**
 * dlib_confl_dump
 * @brief dump out confl all items.
 * @param confl: confloose structure
 */
extern void dlib_confl_dump(dlib_confl_t *confl);

#ifdef __cplusplus
}
#endif
#endif
